<template>
  <!-- 图片上传
   multiple：多选
   accept：文件类型
   limit：最大上传数量
   list-type: 图片类型
   :auto-upload="false"  关闭自动上传
  -->
  <div class="upload-container">

    <el-upload ref="uploadRef" action="#" list-type="picture-card" :auto-upload="false" :multiple="true"
      :file-list="fileList" :on-preview="handlePictureCardPreview" :on-change="handleChange" :on-remove="handleRemove"
      :accept="acceptTypes">
      <el-icon>
        <Plus />
      </el-icon>
    </el-upload>

    <!-- 图片预览弹窗 -->
    <el-dialog v-model="dialogVisible">
      <img w-full :src="dialogImageUrl" alt="图片预览" />
    </el-dialog>


  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { Plus } from '@element-plus/icons-vue'
import type { UploadFile, UploadFiles, UploadInstance } from 'element-plus'
import { ElMessage } from 'element-plus'


// 组件props
interface Props {
  acceptTypes?: string // 可接受的文件类型
  maxSize?: number // 文件最大大小(MB)
  maxCount?: number // 最大上传数量
}

const props = withDefaults(defineProps<Props>(), {
  acceptTypes: 'image/*',
  maxSize: 10,
  maxCount: 10
})

// 上传组件引用
const uploadRef = ref<UploadInstance>()

// 文件列表
const fileList = ref<UploadFiles>([])

// 预览相关
const dialogImageUrl = ref('')
const dialogVisible = ref(false)

// 文件变化时的处理
const handleChange = (file: UploadFile, files: UploadFiles) => {
  // 检查文件大小
  if (file.size && file.size > props.maxSize * 1024 * 1024) {
    ElMessage.warning(` 文件大小不能超过${props.maxSize}MB`)
    removeFile(file.uid.toString())
    return
  }

  // 检查文件类型
  // 检查文件类型是否符合接受类型
  if (props.acceptTypes && file.raw) {
    // 获取文件类型
    const fileType = file.raw.type
    // 将接受类型字符串转换为数组
    const acceptTypes = props.acceptTypes.split(',')
    // 检查文件类型是否在接受类型列表中
    if (!acceptTypes.some(type => {
      // 处理类型通配符
      if (type.endsWith('/*')) {
        // 检查文件类型是否以通配符前缀开始
        return fileType.startsWith(type.replace('/*', '/'))
      }
      // 检查文件类型是否与接受类型完全匹配
      return fileType === type
    })) {
      // 如果文件类型不匹配，显示警告消息并移除文件
      ElMessage.warning(` 仅支持上传${props.acceptTypes} 类型的文件`)
      removeFile(file.uid.toString())
      return
    }
  }
  // 检查文件数量
  if (props.maxCount && files.length > props.maxCount) {
    ElMessage.warning(` 最多只能上传${props.maxCount} 个文件`)
    removeFile(file.uid.toString())
    return
  }

  fileList.value = files
}

// 移除文件
const handleRemove = (file: UploadFile) => {
  fileList.value = fileList.value.filter(item => item.uid !== file.uid)
}

// 辅助方法：从文件列表中移除文件
const removeFile = (uid: string) => {
  const uidNumber = Number(uid); // 将字符串类型的 uid 转换为 number 类型
  fileList.value = fileList.value.filter(file => file.uid !== uidNumber)
}

// 提交上传
const submitUpload = async () => {
  if (!fileList.value.length) {
    ElMessage.warning(' 请先选择文件')
    return
  }

  try {
    const formData = new FormData()
    fileList.value.forEach(file => {
      if (file.raw) {
        formData.append('file', file.raw)
      }
    })

    // 调用上传API
    const res = await upload(formData)

    if (res.code === 200) {
      ElMessage.success(' 上传成功')
      // 上传成功后清空文件列表
      fileList.value = []
    } else {
      ElMessage.error(res.message || '上传失败')
    }
  } catch (error) {
    ElMessage.error(' 上传出错')
    console.error(' 上传出错:', error)
  }
}


// 自定义上传函数（上传到 OSS）

// 点击图片预览
const handlePictureCardPreview = (file: UploadFile) => {
  dialogImageUrl.value = file.url || ''
  dialogVisible.value = true
}

defineExpose({ submitUpload }) // 暴露方法给父组件调用
</script>

<style scoped>
.upload-container {
  max-width: 600px;
  margin: 20px auto;
}
</style>
